﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "GnufExtension.h"
#include <functional>

namespace gnuf
{
    class BnufLeafNodeData;
    class GNUF_EXTENSION_EXPORT GnufTreeNodeData
    {
    public:
        static gcmp::OwnerPtr<GnufTreeNodeData> make(const std::wstring& name, const std::wstring& identity = std::wstring());
        virtual ~GnufTreeNodeData();

    public:
        GnufTreeNodeData* parent();
        const GnufTreeNodeData* parent() const;
        std::vector<gcmp::OwnerPtr<GnufTreeNodeData>>& children() { return m_subNodes; }
        const std::vector<gcmp::OwnerPtr<GnufTreeNodeData>>& children() const { return m_subNodes; }

        void setData(const std::wstring& key, const gcmp::Any& data);
        bool isDataExist(const std::wstring& key) const;
        gcmp::Any& data(const std::wstring& key);
        const gcmp::Any& data(const std::wstring& key) const;

        void setName(const std::wstring& name);
        std::wstring name() const;

        std::wstring identity() const;
        const std::wstring& path() const { return m_path; }

        void sort(const std::function<bool(const gcmp::OwnerPtr<GnufTreeNodeData>&, const gcmp::OwnerPtr<GnufTreeNodeData>&)>& comparer);
        void sort();

    public:
        virtual bool isRoot() const { return false; }
        virtual bool isLeaf() const;
        virtual bool addSubNode(const std::wstring& name, const std::wstring& identity = std::wstring());
        virtual bool addSubNode(gcmp::OwnerPtr<GnufTreeNodeData>&& treeNodeData);
        virtual bool deleteSubNode(const GnufTreeNodeData*);
        virtual bool deleteSubNode(const std::wstring& identity);

    public:
        bool operator<(const GnufTreeNodeData& other) const;

    protected:
        virtual bool setParent(GnufTreeNodeData*);
        explicit GnufTreeNodeData(const std::wstring& name, const std::wstring& identity);

    private:
        GnufTreeNodeData(const GnufTreeNodeData&) = delete;
        GnufTreeNodeData& operator=(const GnufTreeNodeData&) = delete;

    private:
        std::wstring m_path;
        std::map<std::wstring, gcmp::Any> m_data;
        std::vector<gcmp::OwnerPtr<GnufTreeNodeData>> m_subNodes;
        GnufTreeNodeData* m_parent;
    };
}



